package hello;

import java.io.IOException;

import javax.annotation.PostConstruct;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import germmy.groovy.RuleService;

@Service
public class RuleEngine implements ApplicationContextAware {

	public ApplicationContext applicationContext = null;
	
	public ClassPathXmlApplicationContext classPathXmlApplicationContext = null;
	
	RuleService ruleService=null;
	
	@Value("rules.xml")
	private Resource resource=null;
	
	private long lastModified;
	
	@PostConstruct
	public void init() throws IOException{//1、这个地方是有技巧的，就是我不处理，但是这个在容器启动时就会报错的。你连容器都起不来，还谈个P。
		reload();
		lastModified=resource.lastModified();
		System.out.println("Rule engine initialized.");
	}
	
	
	public void run(String ruleName,String params){
		if(!classPathXmlApplicationContext.containsBean(ruleName)){
			System.out.println("规则【"+ruleName+"】不存在");//这里不需要抛出异常，程序可以不中断
			return;
		}
		RuleService ruleService=classPathXmlApplicationContext.getBean(ruleName, RuleService.class);
		if(ruleService == null){
			System.out.println("规则【"+ruleName+"】不存在");
			return;
		}
		ruleService.doRule(params);
	}
	
	
	private void reload(){
		//将老的先保存下来
		ClassPathXmlApplicationContext oldClassPathXmlApplicationContext=classPathXmlApplicationContext;
		try {
			classPathXmlApplicationContext=new ClassPathXmlApplicationContext
					(new String[]{resource.getURI().toString()}, applicationContext);
			//将老的销毁
			if(oldClassPathXmlApplicationContext != null){
				oldClassPathXmlApplicationContext.destroy();
			}
		} catch (BeansException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	/**
	 * 检查是否过期，应该用定时任务去驱动
	 */
	@Scheduled(fixedDelay=5000)
	public void checkForUpdate(){
		//如果文件的最后修改日期比我上一次修改的时间要新，说明我就可以去重新加载了
		try {
			if(resource.lastModified()>lastModified){
				reload();
				lastModified=resource.lastModified();//将上次日期更新记录下来
				System.out.println("Rule Engine Updated");
			}
		} catch (IOException e) {
			System.out.println("妈的，找不到配置文件了，日志记录下，一会有人发现，赶紧处理");//测试点2 ，在中途把文件干掉，观察结果
			e.printStackTrace();
		}
	}
	
	
	
	
	
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext=applicationContext;
	}

}
